package com.pan.annotation.aspect;

import com.pan.annotation.EntityNotNull;
import com.pan.excep.error.AspectException;
import com.pan.tools.ApplicationContextUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Aspect
@Component
public class EntityNotNullAspect{



    @Pointcut("@annotation(com.pan.annotation.EntityNotNull)")
    public void annotationCut(){}

    private <T> Integer indexOf(T[] arr,T target){
        for (int i=0;i<arr.length;i++){
            if (arr[i].equals(target)){
                return i;
            }
        }
        return null;
    }


    @Before("annotationCut()")
    public void checkNull(JoinPoint joinPoint){
        Object target =  joinPoint.getTarget();
        String methodName = target.getClass().getName();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Class[] types = methodSignature.getParameterTypes();
        Method method;
        try {
            method = target.getClass().getMethod(methodName,types);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        EntityNotNull entityNotNull = method.getAnnotation(EntityNotNull.class);
        Class daoClass = entityNotNull.daoClass();
        String idName = entityNotNull.idName();
        String[] names = methodSignature.getParameterNames();
        Integer index = indexOf(names,idName);
        if (index==null){
            throw new AspectException(500,"注解设置的参数错误",EntityNotNull.class,method);
        }
        Object[] objs = joinPoint.getArgs();
        Long targetId = (Long)objs[index];
        Object dao = ApplicationContextUtils.getBean(daoClass);
        Method selectMethod;
        try {
            selectMethod = dao.getClass().getMethod("selectById",Long.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        try {
            if (selectMethod.invoke(targetId)==null){
                throw new AspectException(403,"不纯在用户传入id的实体",EntityNotNull.class,method);
            }
        } catch (IllegalAccessException|InvocationTargetException e) {
            throw new AspectException(500,"反射调用dao的selectById方法错误",EntityNotNull.class,method);
        }

    }

}
